package com.reverie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.reverie.common.pojo.CommonPageReq;
import com.reverie.dto.req.GoodQueryParam;
import com.reverie.entity.Goods;
import com.reverie.entity.GoodsAttr;
import com.reverie.entity.GoodsGallery;
import com.reverie.mapper.GoodsMapper;
import com.reverie.service.IGoodsAttrService;
import com.reverie.service.IGoodsGalleryService;
import com.reverie.service.IGoodsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Rui.Zhou
 * @since 2024-02-03
 */
@Service
public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements IGoodsService {

    @Autowired
    private IGoodsAttrService goodAttrService;
    @Autowired
    private IGoodsGalleryService goodGalleryService;

    @Override
    public Page<Goods> queryPage(CommonPageReq<GoodQueryParam> queryPageParam) {
        GoodQueryParam goodQueryParam = queryPageParam.getQueryParam();
        QueryWrapper<Goods> wrapper = new QueryWrapper<>();
        if(goodQueryParam != null){
            if(StringUtils.hasLength(goodQueryParam.getGoodsName())){
                wrapper.lambda().like(Goods::getGoodsName,goodQueryParam.getGoodsName());
            }
            if(goodQueryParam.getIsOnSale() != null){
                wrapper.lambda().eq(Goods::getIsOnSale,goodQueryParam.getIsOnSale());
            }
            if(goodQueryParam.getCatId() != null){
                wrapper.lambda().eq(Goods::getCatId,goodQueryParam.getCatId());
            }
            if(!CollectionUtils.isEmpty(goodQueryParam.getCatIds())){
                wrapper.lambda().in(Goods::getCatId,goodQueryParam.getCatIds());
            }
        }
        wrapper.lambda().orderByDesc(Goods::getGoodsId);
        Page<Goods> goodsPage = new Page<>(queryPageParam.getPageNo(),queryPageParam.getPageSize());
        page(goodsPage,wrapper);

        buildRecords(goodsPage.getRecords());

        return goodsPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean onSave(Goods goods) {
        if(goods.getGoodsId() == null){
            goods.setCatId(5);
            goods.setBelongTo("103");
        }
        saveOrUpdate(goods);

        if(!CollectionUtils.isEmpty(goods.getGoodAttrList())){
            goods.getGoodAttrList().forEach(goodsAttr -> {
                if(goodsAttr.getGoodsAttrId() == null){
                    goodsAttr.setGoodsId(goods.getGoodsId());
                }
            });
            goodAttrService.saveOrUpdateBatch(goods.getGoodAttrList());
        }

        if(!CollectionUtils.isEmpty(goods.getGoodGalleries())){
            goodGalleryService.removeByGoodId(goods.getGoodsId());
            goods.getGoodGalleries().forEach(gallery -> {
                if(gallery.getImgId() == null){
                    gallery.setGoodsId(goods.getGoodsId());
                }
            });
            goodGalleryService.saveOrUpdateBatch(goods.getGoodGalleries());
        }

        return true;
    }

    private void buildRecords(List<Goods> records) {
        if(!CollectionUtils.isEmpty(records)){
            Set<Integer> goodsIds = new HashSet<>();
            records.forEach(good -> {
                goodsIds.add(good.getGoodsId());
            });
            Map<Integer,List<GoodsAttr>> goodAttrMap;
            Map<Integer,List<GoodsGallery>> goodGalleryMap;
            if(!CollectionUtils.isEmpty(goodsIds)){
                List<GoodsAttr> goodsAttrs = goodAttrService.listByGoodIds(goodsIds);
                List<GoodsGallery> goodsGalleries = goodGalleryService.listByGoodIds(goodsIds);
                goodAttrMap = goodsAttrs.stream().collect(Collectors.groupingBy(GoodsAttr::getGoodsId));
                goodGalleryMap = goodsGalleries.stream().collect(Collectors.groupingBy(GoodsGallery::getGoodsId));
            } else {
                goodAttrMap = new HashMap<>();
                goodGalleryMap = new HashMap<>();
            }
            records.forEach(good -> {
                good.setGoodAttrList(goodAttrMap.getOrDefault(good.getGoodsId(),new ArrayList<>()));
                good.setGoodGalleries(goodGalleryMap.getOrDefault(good.getGoodsId(),new ArrayList<>()));
            });
        }
    }
}
